package edu.cmu.vlis.wassup.db;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import edu.cmu.vlis.wassup.databean.Event;
import edu.cmu.vlis.wassup.databean.EventsForUser;
import edu.cmu.vlis.wassup.databean.User;

public class EventsForUserDAO {
	private BeanFactory<EventsForUser> factory;
	
	
	public EventsForUserDAO() throws DAOException {
		try {					
			BeanTable.useJDBC("com.mysql.jdbc.Driver", System.getProperty("org.mybeans.factory.jdbcURL")+
					"?user="+System.getProperty("org.mybeans.factory.user")
					+"&password="+System.getProperty("org.mybeans.factory.password"));
			
			UserDAO userDAO = new UserDAO();
			EventDAO eventDAO = new EventDAO();
			
	        BeanTable<EventsForUser> eventsForUserTable = BeanTable.getInstance(EventsForUser.class, "eventsForUser", 
	        		eventDAO.getFactory(), userDAO.getFactory());
	        
	        if (!eventsForUserTable.exists()) 
	        	eventsForUserTable.create("eventId", "userId");
	        
	        // Long running web apps need to clean up idle database connections.
	        // So we can tell each BeanTable to clean them up.  (You would only notice
	        // a problem after leaving your web app running for several hours.)
	        eventsForUserTable.setIdleConnectionCleanup(true);
	
	        // Get a BeanFactory which the actions will use to read and write rows of the "user" table
	        factory = eventsForUserTable.getFactory();
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}
	
	/**
	 * To check whether the given user and announcement mapping exists
	 * @param announcement_id
	 * @param receiver_id
	 * @return
	 * @throws RollbackException 
	 */
	public boolean isEventExist(Event eventId, User userId) {
		boolean result = false;
		
		try {
			EventsForUser message = factory.lookup(eventId, userId);			
			if (message != null) 
				result = true;
		} catch (RollbackException e) {
			e.printStackTrace();
		}
		
		return result;
		
	}

	/** Insert a new tuple of Announcement_user into the beanTable
	 * Returns error message if creation fails.
	 * Otherwise return a null upon success.
	 * 
	 * @param announcement_id
	 * @param receiver_id
	 * @return
	 * @throws RollbackException
	 */
	public void insert(Event eventId, User userId) throws DAOException 
	{
		try {
			if (!Transaction.isActive())	// If the former transaction does not end normally
				Transaction.begin();	// Begin a new transaction
			
			factory.create(eventId, userId);
			
			Transaction.commit();
		
		} catch (RollbackException e) {
			//e.printStackTrace();
			throw new DAOException(e);
		}		
	}
	
	/** Lookup whether a typical Announcement_User exists in the table
	 * Return Not Found if the addresss information is missing
	 * Otherwise return detailed information about address of a user
	 * 
	 * @param announcement_id
	 * @param receiver_id
	 * @return
	 * @throws RollbackException
	 */
	public EventsForUser lookup(Event eventId, User userId) throws DAOException {
		EventsForUser message = null;
		try {
			message = factory.lookup(eventId, userId);
		} catch (RollbackException e) {
			//e.printStackTrace();
			throw new DAOException(e);
		}		
		return message;
	}
	
	
	/**
	 *  Delete a tuple with primary key as the composite key with Announcement_id and User_id from User_Announcement table
	 * @param announcement_id
	 * @param receiver_id
	 * @return
	 * @throws RollbackException
	 */
	// return null if no tuple is affected
	public void delete(Event eventId, User userId) throws DAOException {
		
		EventsForUser message = lookup(eventId, userId);		
			
		if (message != null) {
			try {
				if (!Transaction.isActive())  
					Transaction.begin();
				factory.delete(eventId, userId);				
				Transaction.commit();
			} catch (RollbackException e) {
				//e.printStackTrace();
				throw new DAOException(e);
			}
		}		
	}
	
	/**
	 * Delete all the messages related to the input user
	 * @param userId
	 * @throws DAOException
	 */
	public void deleteMessage(User userId) throws DAOException {
		EventsForUser[] messages = null;
		try {
			messages = factory.match(MatchArg.equals("userId", userId));
			if (messages != null && messages.length>0) {
				for (EventsForUser message: messages) {
					factory.delete(message.getEventId(), userId);
				}
			}
		} catch (RollbackException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			throw new DAOException(e);
		}
		
	}

	/** 
	 * Get All events for the given User
	 */
	public Event[] getAllEventsForMe(User user) {
		Event[] myEvents = null;
	
		try {
			EventsForUser[] allEvents = factory.match(MatchArg.equals("userId", user));
			
			if (allEvents != null && allEvents.length > 0) { 
				myEvents = new Event[allEvents.length];
				
				for (int i = 0; i < allEvents.length; i++) {			
					myEvents[i] = allEvents[i].getEventId();				
				}			
			}
		} catch (RollbackException e) {
			e.printStackTrace();
		}
		
		return myEvents;
	}

	
	/**
	 * Get all the messages about a certain event - getMessageFromAnnouncement
	 * @param a
	 * @return
	 * @throws RollbackException
	 */
	public EventsForUser[] getEventsForUser(Event event) {
		EventsForUser[] eventsForUsers = null;
		try {
			eventsForUsers = factory.match(MatchArg.equals("eventId",event));
		} catch (RollbackException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return eventsForUsers;
	}
	
	public static void main(String[] args) throws RollbackException {
		try {
			EventsForUserDAO eventsForUserDAO = new EventsForUserDAO();
			System.out.println("Table created !");
			UserDAO userDAO = new UserDAO();
			EventDAO eventDAO = new EventDAO();
			
			Event[] allEvents = eventDAO.getAll();
			
			User user = userDAO.lookup("radhika@cmu.edu");
			
			for (int i = 0; i < allEvents.length; i++) {
				Event event = allEvents[i];
				eventsForUserDAO.insert(event, user);
				System.out.println("Event insterted " + event);
			}
			
			Event[] myEvents = eventsForUserDAO.getAllEventsForMe(user);
			
			for (int i = 0; i < myEvents.length; i++) {
				Event event = myEvents[i];
				System.out.println(event);
			}
			
			System.exit(0);
			
		} catch (DAOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
